home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 22
/
Cream of the Crop 22.iso
/
program
/
tmtpl37o.zip
/
MANUAL.OS2
< prev
next >
Wrap
Text File
|
1996-10-17
|
32KB
|
1,001 lines
Pascal Lite Compiler for OS/2
[ Version 0.33 ]
TMT Development Corporation
Introduction
------------
The TMT Pascal Lite compiler is a fast compiler for the Pascal language.
The compiler emits 32-bit code and supports many language extensions
from Borland Pascal (BP), as well as more powerful extensions.
The compiler requires a floating point co-processor.
This manual consists of the following parts:
- compiler installation and running
- configuration file
- memory organization
- calling convention
- implemented language description:
- restriction
- extensions
- incompatibilities
- units description:
- DOS
- CRT
- USE32
- ERRCODE
- DEBUG
- STRINGS
- OS2ORD
- DOSCALL
- OS2PMAPI
- troubleshooting
- run-time error codes
Compiler installation and running
---------------------------------
The Pascal Lite distribution is contained in the tmtplos2.zip archive.
Please, read the license.doc file before the installation.
Follow these instructions to run the installation process.
- create the \TMTPLOS2 directory on one of the drives (we will call
it the x: drive) using the command:
x> md TMTPLOS2
NOTE::: DO NOT INSTALL THE DOS AND THE OS/2 VERSIONS OF THE COMPILER INTO
THE SAME DIRECTORY. Because of file name conficts, this will make one
of the versions unusable.
- copy the tmtplos2.zip file into the TMTPLOS2 directory:
x> copy tmtplos2.zip x:\TMTPLOS2
x> x:
x> cd \TMTPLOS2
- run the PKUNZIP program to decompress the TMTPLOS2.ZIP
x:\TMTPLOS2> pkunzip -d tmtplos2
(the switch "-d" unpacks with subdirectories)
- modify the PATH statement in the autoexec.bat, to include the
x:\TMTPLOS2\BIN
subdirectory, if you so desire.
and the INCLUDE_PATH statement in x:\TMTPLOS2\BIN\TMTRC.CFG for
the desired resources.
- goto to \TMTPLOS2\EXAMPLES\OS2\HELLO
compile the simple test program, "HELLO.PAS", and run it:
x:\TMTPLOS2\EXAMPLES\OS2> plt hello
x:\TMTPLOS2\EXAMPLES\OS2> hello
- read the entire manual.os2 file before using the compiler for
any "real" application development.
Contents of the distribution
----------------------------
documentation:
manual.os2 - description of the PLT compiler for OS/2.
license.doc - license agreement
readme - this file
executable:
subdirectory BIN\ contains following files:
pltos2.cfg - compiler configuration file
plt.exe - the PLT compiler under OS/2
tmtrc.exe - TMT resource compiler for OS/2 *
tmtrc.msg - TMT resource compiler message file *
tmtrc.mac - TMT resource compiler prologue file *
tmtrc.cfg - TMT resource compiler configuration file *
* not in the free version.
standard library object modules:
subdirectory UNITS\ contains unit files with following extensions:
.FPD - for DOS version
.FPU - for OS/2 version
.FPL - for OS/2 version (for .DLL's)
arg - commmand line parsing unit
crt - crt unit
debug - post-mortem dump unit and other debugging
functions
dos.fpd - dos unit
doscall - low-level DOS interface and OS/2
os2ord - OS/2 function ordinal numbers (OS/2 version only)
os2pmapi - OS/2 presentation manager interface (OS/2 version only)
errcodes - run-time error codes
strings - strings unit
system - system unit
also in this directory contains files:
STUB.EXE - stub for OS/2 executables
DOS32.EXE - DOS32 extender
STUB32.EXE - stub for DOS32 extender
PASSTUB.EXE - PMODE-based extender
example:
subdirectory EXAMPLE\DOS\ contains following examples for MS DOS:
HELLO\ - example "Hello, World" program
FLAME\ - example of direct works with I/O ports and physical
memory
VESADEMO\ - example of import and usage VESA.OBJ file from
DOS32 libraries.
subdirectory EXAMPLE\OS2 contains following example for OS/2:
HELLO\ - example "Hello, World" program
SKELETON\ - example simple presentation manager application
subdirectory EXAMPLE\LIN_EQ contains example of multidimensional
open arrays usage
supplemential files:
full distribution of DOS32 extender for the MS DOS
version of Pascal/Lite
Running the compiler:
--------------------
The compiler is invoked with the "plt" command:
plt [switches] <main file>
where the following switches can be used:
-m - make modified units (default option)
-b - build the whole program
-c - single compilation (without linkage)
-t<target> - define target system for compiling
<target> = DOS - for DOS executables (default under DOS)
<target> = OS2 - for OS/2 executables (default under OS2)
<target> = OS2:FS - for OS/2 full screen executables
<target> = OS2:PM - for OS/2 presentation manage executables
<target> = OS2:DLL - for OS/2 dynamic link libraries
The suite of compiled units (*.FPx) will be created in the same
directory as the sources, and the executable file will be created in the
current directory (if the switch -c is not used).
Configuration file
------------------
Before a compilation the compiler reads the settings from the special file -
pltos2.cfg. It searches for one at the beginning of the current directory and
then, if it doesn't find one, in the starting directory.
The configuration file "pltos2.cfg" contains the compilation parameters:
one command per line. Empty line are possible. Comment lines are started with
the ';' symbol.
The following parameters can be used in the pltos2.cfg:
toggle settings:
w+ - turn on the puting of warning messages
r+ - turn on the range checking
q+ - turn on the overflow checking
i+ - turn on then automatic input/output result checking
t+ - typed pointers
x+ - extended syntax
v+ - strict var checking
optreg+ - turn on the register optimization
optfrm+ - turn on the stack frame optimization
opt+ - turn on all optimization (optreg+ & optfrm+)
Default settings: w+, r+, q+, i+, t-, x+, v+, opt+.
file path search specification:
srcpath <search_path> - specifies path for the source file search
objpath <search_path> - specifies path for the object file (.FPD,
.FPU, .FPL) and STUBs search
objimppath <search_path> - specifies path for the OBJ import file
search by use of a $L directive
pseudo-devices SYS: and SRC: can be used in the path line:
SYS: means the PLT compiler directory,
SRC: means the application program directory.
defaults: srcpath src:;sys:
objpath src:;sys:
objimppath src:;sys:
buffer size specification:
objmax <size> - specifiies the size of the buffer for object
modules (fpd-files). This parameter must be
about one and a half times the size of the
largest fpd-file from the project.
exemax <size> - specifies the maximum size of the executable
module.
defaults: objmax 333000
exemax 256000
These values are enough for ordinary work. But if you receive
a message about overflowing of these buffers, you'll have to
increase them.
stack size specification:
stack <stack_size> - specifies size of the application stack
default: 32000
start up block (stub) name specification:
stub <stub_name> - specifies the STUB name for the linker.
default: STUB.EXE for OS/2 targeted compilation
and DOS32.EXE for DOS targeted compilation
+++0.30
use the OBJPATH option to specify the seacrh path
for the stub files
---0.30
Symbol definition:
def <symbol name>
+++0.30
The following symbols are predefined:
__TMT__ : always
__DOS__ : for DOS target
* __OS2__ : for all OS/2 targets
* __DLL__ : for .DLL targets
* __PM__ : for OS/2 Presentation manager targets
* __FS__ : for OS/2 Full screen targets
* -- OS/2-hosted compiler only
---0.30
error message format specification:
errmw+ - specifies the MetaWare Pascal format of the error message:
E "HELLO.PAS" L4/C16: type mismatch
errmw- - specifies the BP-like format of the error message:
textcolor (lightred+'a');
Error: HELLO.PAS (line 4, col 16): type mismatch
This parameter allows use of the MultiEdit program as a shell
when the errmw+ parameter is set.
The default is: errmw-
output of the Dos32 logo specification:
logo+ - enables output of the Dos32 logo during the running of
the emitted program.
logo- - disables output of the Dos32 logo during the running of
the emitted program.
The default is: logo+
Memory organization under DOS32 extender
----------------------------------------
The PLT compiler uses the Dos32 extender for a protected-mode program.
The full distributive of Dos32 is in the DOS32 subdirectory.
This distributive contains all information about program execution
under the 32-bit mode. Here some important issues are presented.
The segment registers are not used in the protected mode. Instead all
address space is separated on 4Kb pages starting from the zero address.
Every page has a physical equivalent in the special table (the physical
address might not be equal to the logical address). In such a case the
logical address 0 corresponds to the beginning of the program code.
Therefore if you try to access the physical address (video memory and so
on), you will not succeed.
Nevertheless, access to the physical addresses is possible, because
the Dos32 extender reflects physical addresses into another set of special
address pages. To find the logical address from physical, you have to add
the value of the special _zero varible from the SYSTEM unit to the physical
address.
For example:
procedure clr_video (filler: char);
var i: integer;
begin
for i := 0 to 80*25-1 do
mem [_zero+$B8000+i*2] := filler;
end;
This procedure fills the video memory of the VGA adapter with the
filler symbol.
Note that the linear address $B8000 is used as the physical address - not
the segment address $B800.
Some another special variables are described in the SYSTEM unit.
The _psp variable contains the logical 32-bit address of the PSP of the
program, and the _environ variable contains the environment address.
Although you can access the interrupt vectors by using this method,
we do not suggest doing this.
Also keep in mind that MS-DOS interrupt handlers use memory
addresses in the 1st mb of physical memory while your program
and its data are loaded beyond the 1st mb. DOS32 intercepts
and correctly handles some, but not all, calls to MS-DOS.
Thus, if you are using Intr() or MsDos() calls, or call MS-DOS from
the assembler, you will need to modify the code.
Additional details about this and related subjects can be found in
DOS32.DOC and API.DOC in subdirectory DOS32.
Calling conventions
-------------------
Calling conventions match those in Borland Pascal with the following
differences:
all parameters use 4 bytes on the stack, or a multiple of 4 (BP:2)
all procedures must preserve the contents of registers ebx, ecx, edx,
ds, and es!
the direction bit should be cleared after the exit from a procedure,
if it has been modified by it.
Language syntax of TMT Pascal/Fast:
-----------------------------------
While the Language syntax of TMT Pascal/Fast is in general compatible with
BP 7.0, there are some differences. Below is the list, divided into three
groups: limitations, extensions, and incompatibilities.
1. Limitations:
Not implemented are MARK and RELEASE.
The INLINE() operator is implemented in a partial form:
INLINE (byte/byte/...);
(No references to variables/constants are allowed).
The import of object modules does not support all 32bit object formats.
We recommend using TASM which is fully supported (except for
the use of segmented addresses, which is not needed in the flat model).
2. Extensions:
ADA-style comments are supported: -- comment
For example:
space := ' '; -- initialize filler char
Almost everywhere where Pascal's syntax allows a type identifier, we
also allow a type descriptor. The compiler will produce a warning if you
use this feature.
!!! Keep in mind that the rules of type equivalence stay in force.
Procedural values contain the address of the local environment (frame).
Thus, any local procedures can be used in procedural values. Procedural
declaration in the style
procedure p (function f (a:real):real); ...
are also realized.
The procedural value from a method of object can be obtained by
selecting this method from some object value (not from a type). The
parameters of this procedural value must match the parameters of the
method. The invocation of such a procedural value is an invocation of the
corresponding method of the object. The reference to the object is
transferred through the base of the procedural value.
You can use only global procedural values to initialize a type constant.
!!! Procedural values may be used only while the environment where
they were formed is still in existence. Thus, for local procedures
--- until the exit from the block, in which they are described; for
methods --- while the underlying object still exists.
see also "incompatibilities."
With TMT Pascal you can use any statement as a procedure body,
except for the assignment and the procedure calls.
The RESULT variable in the body of such functions denotes the variable
that contains the return value. The RESULT is of the function return type
and may be used as a variable without any restrictions.
With TMT Pascal you can enter the procedure body directly as a procedure
parameter. The procedure or function header (if not specified) takes the
procedural parameter type. If the procedure header is specified, the
procedure name is omitted. Example:
function integral (function f (a:real):real; low, high, step: real): real;
begin ... end;
...
writeln (integral (
function (x:real):real; begin result := sqrt (x) end,
0, 10, 0.1));
writeln (integral (begin result := sqrt (a) end, 0, 10, 0.1));
writeln (integral (
function; -- function keyword needed
var x: real; -- for local declaration
begin x := sqrt (a); result := x end,
0, 10, 0.1));
writeln (integral (
declare; -- other way
var x: real; -- for local variable declaration
begin x := sqrt (a); result := x end,
0, 10, 0.1));
TMT Pascal allows exit from a local procedure to the one that contains it.
This feature is listed in the Pascal's ANSI standard but not realized in
BP. Together with procedural values, this is very useful for error handling:
Program test;
Var on_eof: procedure;
Function read_char: char;
Var c: char;
Begin
If Eof (Input) Then on_eof;
read (c);
read_char := c;
End;
Procedure p;
Label eof_reached;
Procedure go_eof; Begin goto eof_reached; End;
Begin
on_eof := go_eof;
While True Do Write (read_char);
Eof_reached:
Writeln ('*** EOF ***');
on_eof := NIL;
End;
Begin
p;
End.
Restriction: BREAK and CONTINUE operators cannot be used to exit
from a procedure. Use GOTO instead.
Example:
for i := 1 to 10 do
writeln (integral ( -- function integral from previous example
if a < 0 then break else result := sqrt (a), -- incorrect
i, i + 1, 0.01));
declare
label L;
begin
for i := 1 to 10 do
writeln (integral (
if a < 0 then goto L else result := sqrt (a), -- correct
i, i + 1, 0.01));
L: end;
Functions may return any values of any type, including structures and arrays.
The new operator DECLARE
DECLARE
<declaration part>
BEGIN
<statement list>
END
allows one to describe local variables and procedures anywhere in the
program. Use of "DECLARE" leads to more readable programs and conserves
the stack space.
Functions length, chr, ord may be used as variables. For example:
chr (i) := ' '; is equivalent to i := ord (' ');
ord (c) := 255; is equivalent to c := chr (255);
length (s) := 10; is equivalent to s [0] := chr (10);
The main program may contain "interface" and "implementation".
This allows access to the variables of the main program from other
modules:
Program test;
Interface
Var global: Integer;
Implementation
Uses Unit_test;
Begin
Unit_test.write;
End.
Unit Unit_test;
Interface
Procedure Write_global;
Implementation
Uses test;
Procedure Write_global;
Begin
Write (test.global);
End;
End.
!!! Here the name of the file that contains the text of the main program
must be identical with the name that follows the keyword "program".
New type: DWORD - an unsigned 32-bit integer (same as unsigned long in C).
It can be useful in many cases, but keep in mind that during arithmetic
operations between DWORD's and LONGINT's both arguments are cast to
LONGINT's. This may cause an error.
ABSOLUTE may refer to fields of records and objects. Also, the
address of a global record/object field can be used within the initialization
of typed constants. Furthermore one can use recursive initialization:
type rec = record
next: ^rec;
buffer: array [1..10] of char;
buf_adr: pointer;
end;
const cyclic: rec = (next: @cyclic; buf_adr: @cyclic.buffer);
In initialization of structures and objects the fields may go in
an arbitrary order. If a field is not listed, it is zeroed up.
The syntax of the STR operator has been extended:
STR (value[:width[:precision]], ..., dest);
Here STR (name:2, ':', ext:3, dst); is equivalent to
STR (name:2, temp1);
STR (':', temp2);
STR (ext:3, temp3);
dst := temp1 + temp2 + temp3;
Negative field widths in WRITE, WRITELN, and STR left align the value within
its field.
!!! The Strings unit contains additional functions which may be more
convenient than the STR operator.
+++0.30
Multidimensional open arrays:
You can now use in procedure parameters and functions descriptions
"array (<dim>) of <type>", where <dim> is a positive integer constant, defining
the number of dimensions, ánd <type> is the type of the array elements.
To determine the upper bounds of the array, use the "high (array)" function.
It returns a vector of longints ("array [0..<dim>-1] of longint") containing
the upper bounds. The lower bounds are always set to 0. The vector of the lower
bounds can be obtained with a similar function "low".
Example:
procedure print_vector (v: array (1) of double);
var i: integer;
begin
for i := 0 to high (v) [0] do write (v [i]:10:6, ' ');
writeln;
end;
procedure print_matrix (m: array (2) of double);
var i: integer;
begin
for i := 0 to high (m) [0] do print_vector (m [i]);
writeln;
end;
const a: array [1..3, 1..3] of double = ((1,0,2),(2,1,0),(1,2,1));
begin
print_matrix (a);
end.
You can find an example program for solving a system of linear equations in
the directory "EXAMPLES\LIN_EQ".
---0.30
3. Incompatibilities:
Procedural values is 8 bytes long and has the following format:
0 +-----------------------+
| The entry point |
4 +-----------------------+
| The local environment |
8 +-----------------------+
However, a pointer to a procedure is only 4 bytes long and contains only the
address of the entry point. The @ operator verifies that the procedure is
global. Otherwise a range error is generated.
Furthermore, the stack frame structure and parameter passing conventions
differ from those in BP.
Thus the approach used in TVision and CLassLib for writing iterators
cannot be used. However, we offer this correct and reliable (and more
standard) way:
Type list = object
next: ^list;
procedure for_all (procedure body (var v));
end;
Procedure list.for_all;
Var p: ^list;
Begin
p := @self;
repeat
body (p);
p := p^.next;
end;
End;
...
Type int_list = object (list)
value: integer;
function first_positive: ^int_list;
end;
Function int_list.first_positive;
Label OK;
Var res: ^int_list;
Procedure do_item (var v);
Begin
If int_list (v).value > 0 Then
Begin
res := @v;
GoTo OK;
End
End;
Begin
res := nil;
for_all (do_item);
OK:
first_positive := res;
End;
...
Since in the flat model there are no segments, SEG() always returns 0,
while PTR() ignores its first parameter.
!!! Be careful with these functions: in practice, any use of PTR() or SEG()
in your program may require a program modification.
Pseudo-array Mem and MemW are used as follows:
i := MemW [<linear address>]
Note that the segment is not given. Furthermore, the pseudo-arrays
MemD and PortD of type DWORD are available.
See "Memory organization" for more details.
Built-in assembler
------------------
The built-in assembler of TMT Pascal Lite is 32-bit. It is compatible
with the BP's built-in assembler with the following differences:
Since the program created by the Pascal Lite is executed in the flat
model, the far call and jump commands as well as the @Code and @Data symbols
are not implemented.
The ret command:
The ret command without arguments is considered as a ret <parameter block
size> command. If you need to write the ret command without size you should
set 0 explicitly:
ret 0
Code-procedure
Besides the assembler-routine you can use the code-routine. It has the
following differences: the compiler doesn't emit the frame command on
enter and return from the routine (including the ret command), and the local
parameters are based on ESP on the moment of entry.
Example:
function hi (n: word); code;
asm
mov al, byte ptr [n+1]
ret
end;
Supplied units:
---------------
The following units are included:
SYSTEM.FPx - standard library functions
DOS.FPx - MS-DOS and OS/2 system interface.
Corresponds to the DOS unit of BP.
CRT.FPx - Text mode screen interface.
Corresponds to the CRT unit of BP.
USE32.FPx - Define type Integer as 32-bit etc.
ERRCODES.FPx - Run-time error codes.
DEBUG.FPx - Some debugging code.
STRINGS.FPx - String handling functions.
Corresponds to the STRINGS unit of BP.
OS2ORD.FPx - contains ordinal numbers for OS/2 functions
DOSCALL.FPx - contains declaration OS/2 API procedures
OS2PMAPI.FPx - contains declaration OS/2 PM API procedures
Besides these modules, the distribution includes DOSCALL.FPD and ARG.FPD,
which are needed for linkage. These modules should not be called by the user.
The DOS Unit
------------
This corresponds to the DOS unit of BP.
Differences:
Type FarPointer = record ofs: pointer; seg: word end;
The function GetIntVec has the following syntax:
procedure GetIntVec (IntNo: Byte; var Vector: FarPointer);
and not
procedure GetIntVec (IntNo: Byte; var Vector: Pointer);
New procedures:
procedure GetIntVecFar (IntNo: Byte; var Vector: FarPointer);
procedure SetIntVecFar (IntNo: Byte; const Vector: FarPointer);
GetIntVec is equivalent to GetIntVecFar().
SetIntVec is equivalent to SetIntVecFar(), but uses in the segmented
address the current CS.
A header of an interrupt procedure should have the following form:
procedure handler (
eip, eax, ecx, edx, ebx, esp, ebp, esi, edi: dword;
gs, fs, es: word
); interrupt;
The Registers type has this structure:
type Registers =
record
edi, esi, ebp, _res : dword;
case boolean of
true: (ebx, edx, ecx, eax: dword;
flags, es, ds, fs, gs, ip, cs, sp, ss: word);
false: (bl, bh, b1, b2, dl, dh, d1, d2, cl, ch, c1, c2, al, ah: byte);
end;
!!! When using Intr() and MsDos(), keep in mind that the DOS
interrupt handlers can deal only with the addresses from the 1st
megabyte of memory.
The CRT unit
------------
This unit corresponds to the CRT unit of BP.
The USE32 unit
------------
This unit contains redefinitions of integer types for 32-bit computing as follow:
type
SmallInt = System.Integer;
SmallWord = System.Word;
Integer = System.Longint;
Word = System.Longint;
const
MaxInt = high(longint);
type
PByte = ^Byte;
PWord = ^Word;
PLongint = ^Longint;
PSmallInt = ^SmallInt;
PSmallWord = ^SmallWord;
The ERRCODES unit
-----------------
This unit contains constants for error codes, given by RUNERROR(),
and the error_msg(code: Word): String, function that decyphers the error code.
The DEBUG unit
--------------
This module prints out the error code and the call stack in case of a
run-time error. The stack is printed as follows:
RunError #201 (range check error)
Calls stack:
SYSTEM.BOUND_ERROR [chk_fun.inp(21) at 0000000A]
TEST.ASSN [TEST.PAS(61) at 00000015]
TEST.TEST [TEST.PAS(82) at 0000001D]
To use DEBUG, simply list it in the USES clause of the main program.
This module is supplied with source.
Using the debug UNIT increases the .exe module size
!!! Note: call of a procedure with a NULL address is currently diagnosed as
an arithmetic overflow.
The STRINGS unit
----------------
This unit corresponds to the STRING unit of BP.
It also contains additional functions:
Function hex (n: DWord ): String [12];
-- prints the argument in hex.
Function whl (n: LongInt ): String [12];
-- prints the argument as a signed integer.
Function uns (n: DWord ): String [12];
-- prints the argument as an unsigned integer.
Function fix (x: Extended; pr: LongInt): String [15];
-- prints a real with fixed point. pr is the number of digits after the
decimal point.
Function align (str: String; width: LongInt): String;
-- pads the argument up to width with spaces.
spaces are on the right if width>0, and on the left otherwise.
The OS2ORD unit
---------------
This unit is valid only for OS/2. It contains ordinal number for
OS/2 system DLLs
The DOSCALL unit
----------------
This unit is valid only for OS/2. It contains the declaration of the OS/2
API system procedures.
The OS2PMAPI unit
-----------------
This unit is valid only for OS/2. It contains the declaration of the OS/2
presentation manager API procedures.
Possible problems during usage
------------------------------
DOS/Ext programs, generated by TMT Pascal, abend under OS/2. Correction:
- ensure that in "memory settings" the EMS_MEMORY_LIMIT is not equal to 0.
+++0.33
Run-time errors codes
-------- ------ -----
1 Invalid function number
2 File not found
3 Path not found
4 Too many open files
5 File access denied
6 Invalid file handle
12 Invalid file access_code
15 Invalid drive number
16 Cannot remove current directory
17 Cannot rename across drives
18 No more files
100 Disk read error
101 Disk write error
102 File not assigned
103 File not open
104 File not open for input
105 File not open for output
106 Invalid numeric format
150 Disk is write protected
151 Bad drive request struct length
152 Drive not ready
154 CRC error in data
156 Disk seek error
157 Unknown media type
158 Sector not found
159 Printer out of paper
160 Device write fault
161 Device read fault
162 Hardware failure
200 Division by zero
201 Range check error
202 Stack overflow error
203 Heap overflow error
204 Invalid pointer operation
205 Floating point overflow
206 Floating point underflow
207 Invalid floating point operation
208 Overlay manager not installed
209 Overlay file read error
210 Object not initialized
211 Call to abstract method
212 Stream registration error
213 Collection index_out of range
214 Collection overflow error
215 Arithmetic overflow error
216 General protection fault
217 Invalid operation_code
300 File io error
301 Nonmatched array bounds
302 Non local procedure pointer
303 Procedure pointer out of scope
304 Function not implemented
305 Breakpoint error
306 Break by ctrl/C
307 Break by ctrl break
308 Break by other process
309 No floating point coprocessor
---0.33